package org.ihelpuoo.filepool;

import java.io.File;
import java.io.IOException;

import org.ihelpuoo.core.Factory;
import org.ihelpuoo.io.FileUtils;
import org.ihelpuoo.lang.ArrayUtils;
import org.ihelpuoo.lang.NutException;
import org.ihelpuoo.util.Properties;

/**
 * <b>TempFileFactory class:</b>
 * <hr color=grey size=1>
 *
 * Mainten a group of file in temp file pool.
 *
 * @author zozoh  created @ 2007
 *
 */
public class TempFilePoolImpl extends Factory implements TempFilePool
{

	private File	home;
	private int		size;
	private int		fileId;

	public int getCurrentFileId()
	{
		return fileId;
	}

	@Override
	public void init(Properties config) throws NutException
	{
		super.init(config);
		fileId = 0;
		try
		{
			size = Integer.parseInt(config.getString("size"));
		}
		catch (NumberFormatException e)
		{
			size = 0;
		}
		home = FileUtils.findFile(config.getString("home"));
		if (null == home || !home.isDirectory())
			throw new NutException("TempFilePool expect a directory as home!");
		retrieveLastFileId();
	}

	private void retrieveLastFileId() throws NutException
	{
		File[] names = home.listFiles();
		if (names.length > 0)
		{
			File last = retrieveLastFile((File)ArrayUtils.maxInArray(names));
			if (null == last)
				this.fileId = -1;
			else
			{
				int end = last.getAbsolutePath().lastIndexOf('.');
				if (-1 == end)
					end = last.getAbsolutePath().length();
				StringBuffer sb = new StringBuffer();
				for (int i = home.getAbsolutePath().length(); i < end; i++)
				{
					char c = last.getAbsolutePath().charAt(i);
					if (c != '\\')
						sb.append(c);
				}
				this.fileId = Integer.parseInt(sb.toString(),16);
			}
		}
		else
			this.fileId = -1;
	}

	private File retrieveLastFile(File d)
	{
		if (!d.isDirectory())
			return d;
		File[] names = d.listFiles();
		if (names.length == 0)
			return null;
		return retrieveLastFile((File)ArrayUtils.maxInArray(names));
	}

	/**
	 * Client will request from the TempFileFactory by this function. It will increate the 
	 * file id counter (private data field of this class), If the fileId more than the max
	 * size, it will reset fileId to zero. 
	 * 
	 * @param extension: the file extension
	 * @return File object
	 * @throws IOException 
	 * @throws FailToDeleteOldTempFileException: When get the file, and if the file existed. 
	 * it will delete the file. If fail to delete, the exception will be rised.
	 */
	public synchronized File getFile(String extension) throws IOException
	{
		fileId++;
		if (size > 0 && fileId >= size)
			fileId = 0;

		File f = FileUtils.getFileById(fileId,home,extension);

		if (f.exists())
			if (!f.delete())
				throw new FailToDeleteOldTempFileException(f);
		if (!FileUtils.createNewFile(f))
			throw new FailToCreateNewTempFileException(f);
		return f;
	}

	@Override
	public void depose() throws NutException
	{
	}
}
